package com.boomsecret.netty.chat;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author: wangjinliang
 * @date: 2020/10/22
 */
public class NettyChatServerHandler extends ChannelInboundHandlerAdapter {
    private static Set<Channel> CHANNEL_SET = new CopyOnWriteArraySet<>();

    public static void addChannel(Channel channel) {
        CHANNEL_SET.add(channel);
    }

    public static void removeChannel(Channel channel) {
        CHANNEL_SET.remove(channel);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        String clientMsg = byteBuf.toString(CharsetUtil.UTF_8);
        Channel curChannel = ctx.channel();

        curChannel.eventLoop().execute(() -> {
            CHANNEL_SET.forEach(channel -> {
                if (!Objects.equals(curChannel, channel)) {
                    sendMsg(channel, curChannel.hashCode() + "：" + clientMsg);
                }
            });
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();

        Channel curChannel = ctx.channel();
        removeChannel(curChannel);
        final int hashCode = curChannel.hashCode();

        curChannel.eventLoop().execute(()-> {
            CHANNEL_SET.forEach(channel -> {
                if (!Objects.equals(channel, curChannel)) {
                    sendMsg(channel, curChannel.hashCode() + ": 下线了");
                }
            });
        });
    }

    private void sendMsg(Channel ctx, String msg) {
        ctx.writeAndFlush(Unpooled.copiedBuffer(msg.getBytes()));
    }
}
